/**
 * 1201指令测试脚本 - 副将详情查询
 * 测试根据ID查询副将详情的功能
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
    server: {
        host: 'localhost',
        port: 3000,
        protocol: 'http'
    },

    // 测试用户信息
    testUser: {
        mobile: '17091271111',
        password: '123456',
        passwordHash: 'e10adc3949ba59abbe56e057f20f883e' // 123456的SHA256
    }
};

class DeputyDetailTester {
    constructor() {
        this.token = null;
        this.userId = null;
        this.ws = null;
        this.testResults = [];
    }

    // 运行完整测试流程
    async runTest() {
        console.log('👥 开始1201指令副将详情查询测试...\n');
        console.log('测试目标：HTTP登录 → WebSocket连接 → 测试1201指令详情查询\n');

        try {
            // 1. HTTP登录
            await this.testHttpLogin();

            // 2. 建立WebSocket连接
            await this.testWebSocketConnection();

            // 3. 测试1201指令 - 查询存在的副将
            await this.testQueryDeputyDetail(607); // 燕云狼骑

            // 4. 测试1201指令 - 查询另一个副将
            await this.testQueryDeputyDetail(643); // 黄巾骑兵

            // 5. 测试1201指令 - 查询不存在的副将
            await this.testQueryDeputyDetail(99999);

            // 6. 测试参数验证
            await this.testParameterValidation();

            // 7. 断开连接
            await this.testDisconnect();

            // 输出测试结果
            this.printTestResults();

        } catch (error) {
            console.error('❌ 测试过程中发生错误:', error.message);
            this.addTestResult('整体测试', false, error.message);
        }
    }

    // 1. HTTP登录测试
    async testHttpLogin() {
        console.log('🔐 步骤1: HTTP登录测试...');

        try {
            // 首先尝试注册用户（如果不存在）
            await this.registerUser();

            // 执行登录
            const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });

            if (loginData.code === 0 && loginData.data) {
                this.userId = loginData.data.userId;
                this.token = loginData.data.accessToken;

                console.log(`✅ 登录成功: userId=${this.userId}, token=${this.token.substring(0, 8)}...`);
                this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);
            } else {
                throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
            }

        } catch (error) {
            console.log('❌ 登录失败:', error.message);
            this.addTestResult('HTTP登录', false, error.message);
            throw error;
        }
    }

    // 注册用户（如果不存在）
    async registerUser() {
        try {
            const res = await this.makeHttpRequest('/user-service/user/register', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash,
                captcha: '123456' // 模拟验证码
            });
            console.log('📝 用户注册成功', res);
        } catch (error) {
            // 如果用户已存在，忽略错误
            if (error.message.includes('MOBILE_EXISTS') || error.message.includes('已存在')) {
                console.log('👤 用户已存在，跳过注册');
            } else {
                console.log('⚠️ 注册失败:', error.message);
            }
        }
    }

    // 2. WebSocket连接测试
    async testWebSocketConnection() {
        console.log('\n🔌 步骤2: WebSocket连接测试...');

        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
                this.ws = new WebSocket(wsUrl);

                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');
                    this.addTestResult('WebSocket连接', true, '连接建立成功');

                    // 设置消息监听器
                    this.setupMessageHandler();

                    // 等待连接完全稳定
                    await this.delay(500);
                    resolve();
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    this.addTestResult('WebSocket连接', false, error.message);
                    reject(error);
                });

                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });

                // 连接超时
                setTimeout(() => {
                    if (this.ws.readyState === WebSocket.CONNECTING) {
                        this.ws.close();
                        reject(new Error('连接超时'));
                    }
                }, 10000);

            } catch (error) {
                reject(error);
            }
        });
    }

    // 设置消息处理器
    setupMessageHandler() {
        this.ws.on('message', (data) => {
            try {
                const message = JSON.parse(data.toString());
                console.log('📨 收到消息:', JSON.stringify(message, null, 2));
            } catch (error) {
                console.error('❌ 消息解析失败:', error.message);
            }
        });
    }

    // 3. 测试1201指令查询副将详情
    async testQueryDeputyDetail(deputyId) {
        console.log(`\n👥 步骤3: 测试1201指令 - 查询副将详情 (ID: ${deputyId})...`);

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult(`1201指令测试(ID:${deputyId})`, false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            // 设置响应监听器
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 1201) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0) {
                            console.log('✅ 1201指令查询成功');
                            console.log(`📊 查询结果:`, JSON.stringify(message, null, 2));

                            // 验证返回数据结构
                            const validation = this.validateDeputyDetailResponse(message);
                            if (validation.isValid) {
                                console.log('✅ 返回数据结构验证通过');
                                this.addTestResult(
                                    `1201指令测试(ID:${deputyId})`,
                                    true,
                                    `查询成功: 名称=${message.data.name}`
                                );
                            } else {
                                console.log('❌ 返回数据结构验证失败');
                                this.addTestResult(
                                    `1201指令测试(ID:${deputyId})`,
                                    false,
                                    `数据结构错误: ${validation.errors.join(', ')}`
                                );
                            }
                        } else {
                            console.log(`❌ 1201指令查询失败: ${message.msg || '未知错误'}`);
                            this.addTestResult(
                                `1201指令测试(ID:${deputyId})`,
                                false,
                                message.msg || '查询失败'
                            );
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 1201指令响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1201指令测试(ID:${deputyId})`, false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            // 发送1201请求
            const requestData = {
                c: 1201,
                d: {
                    id: deputyId
                }
            };

            console.log(`📤 发送1201请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            // 设置超时
            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1201指令测试(ID:${deputyId})`, false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 4. 测试参数验证
    async testParameterValidation() {
        console.log('\n🔍 步骤4: 测试参数验证...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('参数验证测试', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            // 设置响应监听器
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 1201) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === -1) {
                            console.log('✅ 参数验证成功 - 正确返回错误');
                            console.log(`📊 错误信息:`, message.msg);
                            this.addTestResult('参数验证测试', true, `参数验证通过: ${message.msg}`);
                        } else {
                            console.log('❌ 参数验证失败 - 应该返回错误但没有');
                            this.addTestResult('参数验证测试', false, '参数验证失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 参数验证响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('参数验证测试', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            // 发送缺少参数的1201请求
            const requestData = {
                c: 1201,
                d: {
                    // 故意不提供id参数
                }
            };

            console.log(`📤 发送缺少参数的1201请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            // 设置超时
            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('参数验证测试', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 验证副将详情响应数据结构
    validateDeputyDetailResponse(message) {
        const errors = [];
        const requiredFields = ['act_id', 'code', 'data'];

        // 检查必需字段
        requiredFields.forEach(field => {
            if (!(field in message)) {
                errors.push(`缺少字段: ${field}`);
            }
        });

        // 检查字段类型
        if (message.act_id !== 1201) {
            errors.push('act_id应为1201');
        }
        if (message.code !== 0) {
            errors.push('code应为0');
        }
        if (typeof message.data !== 'object' || message.data === null) {
            errors.push('data应为对象');
        }

        // 检查data字段结构
        if (message.data && typeof message.data === 'object') {
            const dataRequiredFields = ['name', 's', 'ap', 'czl', 'hp', 'mp', 'sp', 'descr'];
            dataRequiredFields.forEach(field => {
                if (!(field in message.data)) {
                    errors.push(`data缺少字段: ${field}`);
                }
            });
        }

        return {
            isValid: errors.length === 0,
            errors: errors
        };
    }

    // 5. 断开连接
    async testDisconnect() {
        console.log('\n🔌 步骤5: 断开WebSocket连接...');
        if (this.ws) {
            this.ws.close();
        }
        this.addTestResult('断开连接', true, '连接已断开');
    }

    // 添加测试结果
    addTestResult(testName, success, message) {
        this.testResults.push({
            test: testName,
            success: success,
            message: message,
            timestamp: new Date().toISOString()
        });
    }

    // 打印测试结果
    printTestResults() {
        console.log('\n📊 测试结果汇总:');
        console.log('='.repeat(50));

        let successCount = 0;
        let totalCount = this.testResults.length;

        this.testResults.forEach((result, index) => {
            const status = result.success ? '✅' : '❌';
            console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
            if (result.success) successCount++;
        });

        console.log('='.repeat(50));
        console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

        if (successCount === totalCount) {
            console.log('🎉 所有测试通过！');
        } else {
            console.log('⚠️  部分测试失败，请检查日志');
        }

        // 输出功能说明
        console.log('\n📋 1201指令功能说明:');
        console.log('='.repeat(50));
        console.log('指令: 1201 - 根据ID查询副将详情');
        console.log('参数:');
        console.log('  id: 副将ID');
        console.log('返回:');
        console.log('  data: 副将详情对象');
        console.log('    name: 副将名称');
        console.log('    s: 星级');
        console.log('    ap: 攻击力范围');
        console.log('    czl: 成长率范围');
        console.log('    hp: 生命值范围');
        console.log('    mp: 魔法值范围');
        console.log('    sp: 速度范围');
        console.log('    descr: 描述');
    }

    // HTTP请求工具方法
    async makeHttpRequest(path, method = 'GET', data = null) {
        return new Promise((resolve, reject) => {
            const options = {
                hostname: CONFIG.server.host,
                port: CONFIG.server.port,
                path: path,
                method: method,
                headers: {
                    'Content-Type': 'application/json',
                }
            };

            if (data) {
                const postData = JSON.stringify(data);
                options.headers['Content-Length'] = Buffer.byteLength(postData);
            }

            const req = http.request(options, (res) => {
                let body = '';

                res.on('data', (chunk) => {
                    body += chunk;
                });

                res.on('end', () => {
                    try {
                        const responseData = JSON.parse(body);
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(responseData);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${responseData.message || body}`));
                        }
                    } catch (error) {
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(body);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${body}`));
                        }
                    }
                });
            });

            req.on('error', (error) => {
                reject(error);
            });

            if (data) {
                req.write(JSON.stringify(data));
            }

            req.end();
        });
    }

    // 延迟函数
    async delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

// 运行测试
async function main() {
    const tester = new DeputyDetailTester();
    await tester.runTest();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch((error) => {
        console.error('💥 测试脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = DeputyDetailTester;


